Astro
Astro is a site generator tool that focuses on site speed. It supports static site generation (SSG), server side rendering (SSR), and a hybrid between the two (as of Astro 2.0).
It's main feature is Islands where it ships no javascript by default, and only shipping javascript when it's actually necessary. You can also use your components from pretty much any other framework!
Using Astro
Their documentation is great. I recommend using the searchbar on their docs site. Nevertheless, I have included some items here.
Astro NPM Commands
npm create astro@latest
to create Astro projectnpm run dev
uses Vite to start Astro dev servernpm run build
builds production site to./dist/
npm run preview
serves./dist/
to test deployment
Folder Structure
- Everything happens in the
src
folder, it is processed by astro- Inside is the
pages
folder. Everything in here is automatically a route index.astro
is the homepage, likewebreaper.dev
- Ex. if you have
about.astro
it is atwebreaper.dev/about
- Ex. if you have
- Inside is the
public
is at base root of server. Astro will not touch it. This is a good place to put images for exampleastro.config.mjs
is config setup for Astro
Routing
Anything under the pages
directory is automatically a route.
pages/index.astro
is at the base route (/)
pages/about.astro
is at /about
pages/blog/index.astro
is at /blog
Layouts (Templates)
You use "slots" to create layouts in astro. These are conventionally stored as src/layouts
. In your layout .astro
file you put <slot />
. Whenever you wrap and astro page in the template, whatever you wrap will go inside the <slot>
tag.
You can also have named slots (for multiple slots in the same layout) and fallback content. See info about that in the astro docs.
---
const {title} = Astro.props;
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
</head>
<body>
<slot>
"Default if nothing is passed in"
</slot>
</body>
</html>
Then use it like
---
import MainLayout from "../layouts/MainLayout.astro";
---
<MainLayout title="About">
Hello World!
</MainLayout>
Static Site Generation (SSG) vs Server Side Rendering (SSR)
SSG's are lightning fast with pre-build HTML pages. But if you change any part of your site, the entire site has to be re-built and re-deployed. This is not good for sites that need dynamically generated info.
SSR's generate on-demand HTML. This responds to data changes, but you don't get the speed benfits of pre-generated HTML.
Astro's hybrid approach allows you to select which you want for each page individually
SSG Page Examples
- Homepage
- Blog Pages
SSR Page Examples
- Store pages
- Adding a public API to your site
- Large sites with hundreds of routes generated by
getStaticPaths
- Build times improve up to 30% by switching dynamic routes to SSR
Astro Islands
Astro islands extract the UI into smaller, isolated components. Unused javascript is replace with lightweight HTML for faster loads and time-to-interactive (TTI). The astro core concept docs on this can be found here.
You can define which parts of your website need javascript, and which do not. Any javascript in frontmatter will be run server side or at build time. Any javascript within <script>
tags will run client side. You can use <script></script>
tags in your .astro
files. You can also use client:*
directives to make componente interactive (hydrated). Example: <Button client:load />
where Button is a jsx component with state.
You can also "lazy-load" them, which means components don't hydrate until they scroll into view. This allows the HTML to be loaded fast so the user can see things quickly, and then become interactive once the JS can finish loading.
Hydration is the process where client-side JS converts to a static HTML page.
Available client directives and examples can be found here.
Swiper Example
This uses react for the swiper. See my code here.
Astro Integrations
Astro has many integrations, which you can search through on their integrations page. Supported features you can add with npx astro add
, other ones you use the usual npm install
. Some useful ones I have noted below.
- Tailwind - install with
npx astro add tailwind
and it auto-configures for you - React - install with
npx astro add react
and it auto-configures for you - Netlify
- astro-netlify-cms - open source, git based CMS that integrates with Netlify and Jamstack architecture
- Prism - syntax highlighting for code blocks
- Sitemap - generates an xml sitemap, you need this
- MDX - use React components in markdown files
- robots-txt - generates and syncs the robots.txt file with astro config
- astro-icon - a ton of icons from various sources that inline as SVGs
- astro-embed-youtube
- astro-google-fonts-optimizer
- Partytown - Lazy-loading library to make sure third-party scripts (like analytics or ads) don't slow down your site. Use this!
- RSS - Astro RSS integration
- Analytics - snippets injection for popular web analytics tools
- Astro-seo - helper for adding useful SEO info to your pages
- Odyssey Theme - modern theme/starter for business or startup's marketing website
UI Frameworks
Astro only supports some frameworks due to how it manages javascript. Some that it supports include Tailwind (first class support!), Bootstrap, Vanilla Extract.
Within Tailwind, there are a ton of component frameworks you can use. Some of those are Daisy UI, Tailblocks, Tailwind UI, and Flowbite.
Some that Astro does NOT support include Material UI, and Mantine. This is because they rely on CSS in Javascript.
CSS Styling
You can inline style like <p style="classnames">Text</p>
like normal HTML. You can also do <p style={{backgroundColor:"red"}}>Text</p>
.
Can also add style tag directly in component. These only have local scope! The below example only affects the h1's of this page.
---
import MainLayout from "../layouts/MainLayout.astro";
---
<MainLayout title="About">
<h1>About page!</h1>
</MainLayout>
<style>
h1 {
background-color: gold;
}
</style>
If you want the styles to apply for all, see the below.
---
import MainLayout from "../layouts/MainLayout.astro";
---
<MainLayout title="About">
<h1>About page!</h1>
</MainLayout>
<style is:global>
h1 {
background-color: gold;
}
</style>
Other Languages
You can also use other languages, like scss. This will require other dependencies, like npm i -D sass
.
<style lang="scss">
h1{
background-color: gold;
&:hover {
background-color: blue;
}
}
</style>
Global CSS
For using global css, create the css file under src
, like src/styles/global.css
. Import it in whatever files you want to use it in (can do your template), in frontmatter.
---
import "../styles/global.css";
const { title } = Astro.props;
---
Post CSS
Recommend using Post CSS if not using Tailwind npm i postcss postcss-preset-env
postcss-preset-env. You will need to add file postcss.config.cjs
.
module.exports = {
plugins: [
require("postcss-preset-env")({
stage: 0,
}),
],
};
Then in package.json
you need
"browserslist": [
"defaults"
],
Passing Classes to Components
---
export interface Props {
text: string; // button text
href: string; // href
hidey: boolean; // if {true}, then button will be hidden on small devices
}
const { text, href, hidey } = Astro.props;
---
<a
href={href}
class:list={[
"p-3 px-6 pt-2 text-white bg-brightRed rounded-full baseline hover:bg-brightRedLight",
{ "hidden md:block": hidey, block: !hidey },
]}>{text}</a
>
Use it like
---
import ButtonPrimary from "../ButtonPrimary/ButtonPrimary.astro";
---
<ButtonPrimary text="Get Started" href="" hidey={true} />
Icons
Use the package astro-icons with npm i astro-icon
.
Their icon list can be found here.
I have had issues with certain icon sets. Some that have NOT worked for me include "material-symbols" and "ri".
Some that HAVE worked for me are "mdi", "iconoir", "tabler".
Extras
AWS Adapter for Astro
Can use SST to build full-stack apps on AWS. Works with Astro, Next.js, Remix, and Solid and allows you to add backend features like a database, GraphQL API, Auth, Cron jobs, and any other AWS service.
Build an Astro blog
Great youtube video I followed while learning the basics of Astro.